iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
1
AI & Data

資料工程師修煉之路系列 第 17

[Day 17] Encoding and Evolution (4-2) - Avro Evolution

  • 分享至 

  • xImage
  •  

接續 Day 16

Writer's schema and Reader's schema

這裡 Avro 把 encoding 跟 decoding 動作分成 Writer (寫入者) 和 Reader (讀取者),也就是寫入時會有 寫入者的 schema,讀取時也會有讀取者的 schema,因為應用軟體會進化、改變的關係, 2 邊的 schema 有時會不同,所以 Avro 是怎麼做到並存呢?

當 Avro 讀取資料時,它會同時看寫入者跟讀取者的 schema,然後從寫入者的 schema 翻譯資料到讀取者的 schema 裡,如下圖說明:

figure_4-6

這裡可以看到,不會因為 2 邊欄位的順序不同造成問題,Avro 在解析時會一個欄位名接著一個欄位名解析,若寫入者 schema 有該欄而讀取者 schema 沒有,則 Avro 會忽略,若讀取者有新欄位而寫入者沒有,則會以讀取者 schema 所設定的方式給定預設值,整成成表格後如下:

寫入者的 schema 讀取者的 schema App Action
Y N 忽略
N Y 用讀取者 schema 定義的來給預設值

schema 進化的規則

向後兼容代表你寫入者的 schema 是新的,而讀取者的 schema 是舊的,反過來說,

向前兼容代表你寫入者的 schema 是舊的,而讀取者的 schema 是新的,

所以為了保持一致性,你可能只能 新增刪除 帶有 預設值 的欄位,舉例來說,如果你 新增 一欄位是沒有預設值的,新讀取者將無法讀取舊寫入者的資料,這就破壞了向前兼容,再繼續說若你 刪除 了一個沒有預設值的欄位,則舊的讀取者將無法讀取新寫入者寫入的資料,這就破壞了向後兼容。

在某些程式語言,null 是可被允許的預設值,但它不是一個 Avro 用的欄位型態,你可以用另一種 Avro 支援的方式: union type 來讓預設值設為 null;舉例來說,有一欄位型態為 union { null, long, string} ,它說明了該欄位可以是 null、long 或 string,此時你就可以把預設值設定為 null,只要它是在 union 中的某個分支型態之一就 OK,

因此,Avro 沒有像 Thrift 和 Protocol Buffers 那樣的 requiredoptional 的標註,取而代之就是用 union 加預設值來實現。

其他的改變可能嗎?

改變欄位資料型態是沒問題的,Avro 會幫我們轉換型態,

改變欄位名稱也是沒問題但有點 tricky,讀取者的 schema 可以為改變後欄位名取 alias name (別名),之後它就可以對舊寫入者資料用 alias name 來解析,所以向後兼容沒問題,但向前兼容就 GG 了 (舊讀取者遇到不認識的 schema 會忽略),同理新增 union 裡頭的型態也是一樣的。

明天會講 Encoding and Evolution 的最後一段。


上一篇
[Day 16] Encoding and Evolution(4) - Avro
下一篇
[Day 18] Encoding and Evolution (5-1) - Mode of Dataflow - DB, REST API, RPC
系列文
資料工程師修煉之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言